home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Interactive 4
/
PC World Interactive 4.iso
/
online
/
appbar.EXE
/
cppsrc
/
AppBar.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-15
|
20KB
|
722 lines
// *********************************************************
// AppBar -- Advanced Menu bar for Windows 95/NT
// All code Copyright (C) 1995, 1996 by Mike Perham
// mperham@cs.cornell.edu
//
// This code MAY NOT be used for any other program without
// my permission and is forbidden in any shareware/commercial
// program. This code is provided for educational use only
// and there are no guarantees or promises implied. Blah blah
// *********************************************************
///////////////////////////////////////////////////////////////////////
// AppBar - the Application behind the window
// This file encapsulates all I/O, Registry functions,
// initialization, etc.
/////////////
//
// Known Bugs:
//
// Screen saver will not activate in Win95 unless
// AppBar is autohidden. This must be a problem with
// Win95, since it works in all cases under NT4.
//
// Buttons in Edit Dialog are always gray. If
// you change the default color of your dialogs,
// they will stick out like a sore thumb. This is
// because bitmaps do not have a transparent color
// unlike icons (which is what the C version uses).
//
#include "appbar.h"
#include "globals.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#define new DEBUG_NEW
#endif
///////////////////////////////////////////////////
// Here it is...
AppBar ab;
///////////////////////////////////////////////////
// global variables visible in all classes
menu_struct *glob_menu; // "2D" list of menus and apps
sys_vars sv;
user_vars uv; // variables set in OptDlg
app_list *applist; // linear list of all apps
APPBARDATA abd;
///////////////////////////////////////////////////
// Creates the AppBar window
/////////
BOOL AppBar::ShowAppBar(void)
{
abwin = new AppBarWin;
int flags = (uv.stayontop ? WS_EX_TOPMOST : 0) | WS_EX_TOOLWINDOW;
abwin->CreateEx(flags, (LPCTSTR) ABClass, "AppBar",
WS_POPUP | WS_DLGFRAME, 0,
(uv.bottom ? sv.height - AB_HEIGHT : 0),
AB_WIDTH, AB_HEIGHT, 0, 0, 0);
if (!abwin->m_hWnd)
return FALSE;
CWinThread::m_pMainWnd = abwin;
abwin->ShowWindow(SW_SHOW);
if (sv.newshell)
if (uv.autohide)
abwin->HideAppBar(TRUE);
else
abwin->ModifyTime();
else
abwin->HideAppBar(TRUE);
return TRUE;
}
//////////////////////////////////////////////////
// Set system vars and parse cmd args and get reg keys
// This is the first function executed when AppBar is started
////////
BOOL AppBar::InitApplication(void)
{
HWND OldWnd = FindWindow(NULL, "AppBar");
if (OldWnd) {
BringWindowToTop(OldWnd);
return FALSE;
}
#ifdef _DEBUG
begin.Checkpoint(); // Begin debug memory trace
#endif
/* //This does not compile for some unknown reason
OSVERSIONINFO ovi;
ovi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO)
GetVersionEx((LPOSVERSIONINFO)&ovi);
switch (ovi.dwPlatformId) {
case VER_PLATFORM_WIN32_WINDOWS:
sv.newshell = TRUE;
sv.power = FALSE;
break;
case VER_PLATFORM_WIN32_NT:
if (ovi.dwMajorVersion == 4) {
sv.newshell = TRUE;
sv.power = FALSE;
} else if (ovi.dwMajorVersion == 3) {
sv.newshell = FALSE;
sv.power = FALSE;
} else {
sv.newshell = TRUE;
sv.power = TRUE;
}
break;
default:
return FALSE;
}
*/
DWORD dwVersion = GetVersion();
DWORD dwMajor = (DWORD)(LOBYTE(LOWORD(dwVersion)));
DWORD dwMinor = (DWORD)(HIBYTE(LOWORD(dwVersion)));
if (dwVersion < 0x80000000) { // Windows NT
if (dwMajor == 3) {
sv.newshell = FALSE;
sv.power = FALSE;
} else if (dwMajor == 4) {
sv.newshell = TRUE;
sv.power = FALSE;
} else { // NT5!
sv.newshell = TRUE;
sv.power = TRUE;
}
} else if (dwMajor < 4) // Win32s
return FALSE;
else { // Windows 95 -- No build numbers provided
sv.newshell = TRUE;
sv.power = TRUE;
}
if (sv.power) {
SYSTEM_POWER_STATUS sps;
GetSystemPowerStatus(&sps);
if (sps.ACLineStatus)
sv.battery = FALSE;
else
sv.battery = TRUE;
}
sv.width = GetSystemMetrics(SM_CXSCREEN);
sv.height = GetSystemMetrics(SM_CYSCREEN);
// copy AppBar's directory to origdir
char *end = strrchr(m_pszHelpFilePath, '\\');
char *front = (char *) m_pszHelpFilePath;
char *copy = origdir;
while (front != end) {
*copy = *front;
copy++; front++;
}
*copy = '\0';
SetRegistryKey("Software\\AppBar");
// parse args AND get registry keys
ParseCmdArgs();
LPCTSTR temp;
temp = AfxRegisterWndClass(NULL, NULL, (HBRUSH)COLOR_MENU+1, LoadIcon(IDI_APPBAR));
ABClass = CString(temp);
return TRUE;
}
BOOL AppBar::InitInstance()
{
if (!ReadInApps())
return FALSE;
return ShowAppBar();
}
//////////////////////////
// Reads in the user spec'd applications
BOOL AppBar::ReadInApps(void)
{
FILE *appfile;
int i, j=0, ver;
BOOL exist = TRUE;
char msg[80];
menu_struct *cur_menu, *nextmenu, *prevmenu;
app_struct *cur_app, *nextapp, *prevapp;
// Create binary data file if none exists
_chdir(origdir);
if ((appfile = fopen(sv.appfile, "r")) == NULL)
exist = FALSE;
// Read application data until the end of the file
// this tests for zero-length data files (exist, but are empty)
if (exist)
if (_filelength(_fileno(appfile)) == 0)
exist = FALSE;
glob_menu = NULL;
if (exist) {
fread(&ver, sizeof(int), 1, appfile);
if (ver != APPBAR_FILE_VERSION) {
error(OLD_DATAFILE_FORMAT);
return FALSE;
}
cur_menu = new menu_struct;
glob_menu = cur_menu;
nextmenu = cur_menu;
prevmenu = NULL;
while (fread(nextmenu, sizeof(menu_struct), 1, appfile)) {
j++;
cur_menu = nextmenu;
cur_menu->nextapp = NULL;
prevapp = NULL;
cur_menu->prevmenu = prevmenu;
if (nextmenu->numapps) {
cur_app = new app_struct;
cur_menu->nextapp = cur_app;
for (i=cur_menu->numapps;i>0; i--) {
if (!fread(cur_app, sizeof(app_struct), 1, appfile)) {
sprintf(msg, ERROR_READING_MENUS,j,
cur_menu->numapps - i + 1, sv.appfile);
error(msg);
}
cur_app->prevapp = prevapp;
prevapp = cur_app;
if (i-1) {
cur_app->nextapp = new app_struct;
cur_app = cur_app->nextapp;
} else cur_app->nextapp = NULL;
}
}
prevmenu = cur_menu;
nextmenu = new menu_struct;
nextmenu->prevmenu = cur_menu;
cur_menu->nextmenu = nextmenu;
}
// Reached EOF. Now we need to delete that last menu, since it was
// created before we knew it was EOF.
delete nextmenu;
cur_menu->nextmenu = NULL;
fclose(appfile);
} else {
// Create default menu structure if no datafile exists
char path[80];
menu_struct *tempmenu;
tempmenu = new menu_struct;
strcpy(tempmenu->menuname,"&Apps");
tempmenu->numapps = 2;
tempmenu->nextapp = new app_struct;
strcpy(tempmenu->nextapp->appexe, "c:\\vc40\\bin\\msdev.exe");
strcpy(tempmenu->nextapp->appname, "Visual &C++ v4.0");
cur_app = tempmenu->nextapp;
nextapp = new app_struct;
cur_app->nextapp = nextapp;
nextapp->prevapp = cur_app;
strcpy(nextapp->appexe, "c:\\winword\\winword.exe");
strcpy(nextapp->appname, "&Word v7.0");
glob_menu = tempmenu;
tempmenu = new menu_struct;
glob_menu->nextmenu = tempmenu;
tempmenu->prevmenu = glob_menu;
strcpy(tempmenu->menuname,"&Games");
tempmenu->numapps = 2;
tempmenu->nextapp = new app_struct;
GetWindowsDirectory(path, sizeof(path));
strcat(path,"\\winmine.exe");
strcpy(tempmenu->nextapp->appexe, path);
strcpy(tempmenu->nextapp->appname, "&Minesweeper");
cur_app = tempmenu->nextapp;
nextapp = new app_struct;
cur_app->nextapp = nextapp;
nextapp->prevapp = cur_app;
GetWindowsDirectory(path, sizeof(path));
strcat(path,"\\sol.exe");
strcpy(nextapp->appexe, path);
strcpy(nextapp->appname, "&Solitaire");
}
return TRUE;
}
//////////////////////////////////////////////////
// Exit function for appbar
void AppBar::ExitAppBar(BOOL error_exit)
{
if (!error_exit) { // if error, just bomb out...
SaveMenu();
SaveRegKey();
release_app_memory();
}
CleanUp();
PostQuitMessage(0);
}
//////////////////////////////////////////////////
// Delete and unregister all variables and structs
void AppBar::CleanUp(void)
{
if (abwin) {
if (sv.newshell) {
abd.cbSize = sizeof(APPBARDATA);
abd.hWnd = abwin->GetSafeHwnd();
abd.uEdge = (uv.bottom ? ABE_BOTTOM : ABE_TOP);
abd.lParam = FALSE;
SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd);
SHAppBarMessage(ABM_REMOVE, &abd);
}
abwin->DestroyWindow();
delete abwin;
}
UnregisterClass((LPCTSTR)ABClass, m_hInstance);
#ifdef _DEBUG
end.Checkpoint(); // end memory trace and print stats
diff.Difference(begin, end);
diff.DumpStatistics();
#endif
}
//////////////////////////////////////////////////
// Execute application pointed to by app
BOOL AppBar::ExecuteApplication(app_struct * app)
{
char msg[200];
DWORD error;
if (sv.newshell) {
SHELLEXECUTEINFO sei;
sei.cbSize = sizeof(SHELLEXECUTEINFO);
sei.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_NOCLOSEPROCESS;
sei.hwnd = abwin->m_hWnd;
sei.lpVerb = "open";
sei.lpFile = app->appexe;
sei.lpParameters = app->params;
sei.lpDirectory = app->workingdir;
sei.nShow = app->show;
ShellExecuteEx(&sei);
/* error = GetLastError();
switch (error) {
case ERROR_FILE_NOT_FOUND:
sprintf(msg, FILE_NOT_FOUND, app->appexe);
break;
case ERROR_PATH_NOT_FOUND:
sprintf(msg, PATH_NOT_FOUND, app->appexe);
break;
case ERROR_NOT_ENOUGH_MEMORY:
sprintf(msg, OUT_OF_MEM);
break;
case ERROR_DLL_NOT_FOUND:
sprintf(msg, DLL_NOT_FOUND);
break;
default:
sprintf(msg, RETURNED_ERROR, error);
break;
}
ab_message(msg, abwin->GetSafeHwnd());
return 0;
}*/
} else {
error = (DWORD) ShellExecute(abwin->m_hWnd, "open", app->appexe,
app->params, app->workingdir, app->show);
if (error < 32) {
switch (error) {
case ERROR_FILE_NOT_FOUND:
sprintf(msg, FILE_NOT_FOUND, app->appexe);
break;
case ERROR_PATH_NOT_FOUND:
sprintf(msg, PATH_NOT_FOUND, app->appexe);
break;
default:
sprintf(msg, RETURNED_ERROR, error);
break;
}
ab_message(msg, abwin->GetSafeHwnd());
return 0;
}
}
return 1;
}
//////////////////////////////////////////////////
// it's hideous, but it does the job...
void AppBar::ParseCmdArgs(void)
{
char msg[80];
int j;
user_vars args;
BOOL done = FALSE;
strcpy(sv.user, "");
strcpy(sv.appfile, "");
memset((void*)&args, 0, sizeof(user_vars));
// now process the array of parameters
for (j=1;j<__argc;j++) {
if (!strncmp(__argv[j], "-", 1)) {
if (!strncmp((char*)__argv[j]+1, "s", 1))
args.stayontop = -1;
else if (!strncmp((char*)__argv[j]+1, "c", 1))
args.chime = -1;
else if (!strncmp((char*)__argv[j]+1, "b", 1))
args.bottom = -1;
else if (!strncmp((char*)__argv[j]+1, "a", 1))
args.autohide = -1;
else if (!strncmp((char*)__argv[j]+1, "d", 1))
args.date = -1;
else if (!strncmp((char*)__argv[j]+1, "m", 1))
args.memory = -1;
else if (!strncmp((char*)__argv[j]+1, "t", 1))
args.time = -1;
else if (!strncmp((char*)__argv[j]+1, "u", 1))
args.user = -1;
else if (!strncmp((char*)__argv[j]+1, "f", 1)) {
if ((j+1 <= __argc)) {
char w = *(__argv[j+1]);
// if filename does not start with '-' or '+'
// assume it is a valid filename
if (!((w == '+') || (w == '-')))
strcpy((char *)sv.appfile, __argv[++j]);
else {
j++;
ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
}
} else
ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
} else {
sprintf(msg, UNKNOWN_OPTION, __argv[j]);
ab_message(msg, abwin->GetSafeHwnd());
}
} else if (!strncmp(__argv[j], "+", 1)) {
if (!strncmp((char*)__argv[j]+1, "s", 1))
args.stayontop = 1;
else if (!strncmp((char*)__argv[j]+1, "c", 1))
args.chime = 1;
else if (!strncmp((char*)__argv[j]+1, "a", 1))
args.autohide = 1;
else if (!strncmp((char*)__argv[j]+1, "b", 1))
args.bottom = 1;
else if (!strncmp((char*)__argv[j]+1, "d", 1))
args.date = 1;
else if (!strncmp((char*)__argv[j]+1, "m", 1))
args.memory = 1;
else if (!strncmp((char*)__argv[j]+1, "t", 1))
args.time = 1;
else if (!strncmp((char*)__argv[j]+1, "u", 1))
args.user = 1;
else if (!strncmp((char*)__argv[j]+1, "f", 1)) {
if ((j+1 <= __argc)) {
char w = *(__argv[j+1]);
if (!((w == '+') || (w == '-')))
strcpy((char *)sv.appfile, __argv[++j]);
else {
j++;
ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
}
} else
ab_message(INVALID_FILENAME, abwin->GetSafeHwnd());
} else {
sprintf(msg, UNKNOWN_OPTION, __argv[j]);
ab_message(msg, abwin->GetSafeHwnd());
}
} else // User gave a user configuration
strcpy((char*)sv.user, __argv[j]);
} // end while
if (strcmp((char*)sv.user, ""))
sprintf(sv.appfile, "appbar.%s", sv.user);
GetRegKeys(&args);
}
//////////////////////////////////////////////////
#define SET(a); if (args->a == 1) \
uv.a = TRUE; \
else if (args->a == -1) \
uv.a = FALSE;
void AppBar::GetRegKeys(user_vars *args)
{
HKEY root;
DWORD isnew, type, size = sizeof(user_vars);
LONG rc;
char *p, keyname[80], mike[80];
// each user gets his own key in the registry
if (strlen(sv.user)) {
strcpy(mike, sv.user);
// this loop will not work with Unicode
for (p=mike; p<mike+strlen(mike); p++)
_tolower(*p);
sprintf(keyname, "%s\\%s", m_pszRegistryKey, mike);
} else
sprintf(keyname, "%s\\Default", m_pszRegistryKey);
if (!strcmp(sv.appfile, ""))
strcpy(sv.appfile, "appbar.default");
// create or open key
rc = RegCreateKeyEx(HKEY_CURRENT_USER, keyname, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &root, &isnew);
if (rc != ERROR_SUCCESS) {
ab_message(ERROR_OPENING_REG, abwin->GetSafeHwnd());
uv.stayontop = TRUE;
uv.time = TRUE;
uv.memory = TRUE;
uv.autohide = TRUE;
uv.chime = FALSE;
uv.date = FALSE;
uv.bottom = FALSE;
uv.user = FALSE;
strcpy(uv.wavfile, "");
if (strlen(sv.user))
sprintf(sv.appfile, "appbar.%s", sv.user);
else
strcpy(sv.appfile, "appbar.default");
return;
}
if (isnew != REG_OPENED_EXISTING_KEY)
MakeNewRegKey(root);
else {
rc = RegQueryValueEx(root, "User_Variables", NULL, &type, (PBYTE)&uv, &size);
if (size != sizeof(user_vars)) {
ab_message(OBSOLETE_REG_DATA, abwin->GetSafeHwnd());
RegDeleteKey(root, "User_Variables");
MakeNewRegKey(root);
}
}
RegCloseKey(root);
// modify user vars according to cmd args
SET(date);
SET(memory);
SET(stayontop);
SET(bottom);
SET(autohide);
SET(chime);
SET(time);
SET(user);
if (!sv.newshell)
uv.autohide = TRUE; // autohide is ALWAYS on in WinNT 3
}
//////////////////////////////////////////////////
void AppBar::MakeNewRegKey(HKEY root)
{
char msg[100];
char comma[3] = "";
LONG rc;
if (strcmp(sv.user, ""))
strcpy(comma, ", ");
sprintf(msg, WELCOME_MSG, comma, sv.user);
ab_message(msg, abwin->GetSafeHwnd());
uv.time = TRUE;
uv.stayontop = TRUE;
uv.chime = FALSE;
uv.date = FALSE;
uv.user = FALSE;
uv.bottom = FALSE;
uv.memory = TRUE;
uv.autohide = TRUE;
strcpy(uv.wavfile, "");
rc = RegSetValueEx(root, "User_Variables", NULL, REG_BINARY,
(PBYTE) &uv, sizeof(user_vars));
if (rc != ERROR_SUCCESS)
ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
}
//////////////////////////////////////////////////
void AppBar::SaveRegKey(void)
{
HKEY root;
char keyname[80];
DWORD isnew;
if (strcmp((char*)sv.user, ""))
sprintf(keyname, "%s\\%s", m_pszRegistryKey, sv.user);
else
sprintf(keyname, "%s\\Default", m_pszRegistryKey);
if (RegCreateKeyEx(HKEY_CURRENT_USER, keyname, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &root, &isnew))
ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
if (RegSetValueEx(root, "User_Variables", NULL, REG_BINARY,
(PBYTE)&uv, sizeof(user_vars)))
ab_message(ERROR_SAVING_REG, abwin->GetSafeHwnd());
RegCloseKey(root);
}
void AppBar::SaveMenu(void)
{
app_struct * pCurApp;
menu_struct * pCurMenu;
app_struct *next, *prev, *nexta;
menu_struct *nextm, *prevm;
char msg[80];
FILE *pDataFile;
int i;
_chdir(origdir);
pDataFile = fopen(sv.appfile, "wb"); // Open for binary write
if (!pDataFile) {
sprintf(msg, ERROR_OPENING_DATAFILE, sv.appfile);
ab_message(msg, abwin->GetSafeHwnd());
return;
}
i = APPBAR_FILE_VERSION;
fwrite(&i, sizeof(int), 1, pDataFile);
for (pCurMenu = glob_menu; pCurMenu != NULL; pCurMenu = pCurMenu->nextmenu) {
nextm = pCurMenu->nextmenu;
prevm = pCurMenu->prevmenu;
nexta = pCurMenu->nextapp;
pCurMenu->nextapp = NULL;
pCurMenu->nextmenu = NULL;
pCurMenu->prevmenu = NULL;
fwrite(pCurMenu, sizeof(menu_struct), 1, pDataFile);
pCurMenu->nextapp = nexta;
pCurMenu->nextmenu = nextm;
pCurMenu->prevmenu = prevm;
for (pCurApp = pCurMenu->nextapp; pCurApp != NULL; pCurApp = pCurApp->nextapp) {
next = pCurApp->nextapp;
prev = pCurApp->prevapp;
pCurApp->nextapp = NULL;
pCurApp->prevapp = NULL;
fwrite(pCurApp, sizeof(app_struct), 1, pDataFile);
pCurApp->nextapp = next;
pCurApp->prevapp = prev;
}
}
fclose(pDataFile);
}
///////////////////////////////////////////////////////////////////////////
// C++ Constructors and Destructors //
///////////////////////////////////////////////////////////////////////////
menu_struct::menu_struct()
{
memset((void*)menuname, 0, sizeof(menuname));
numapps = 0;
nextmenu = NULL;
prevmenu = NULL;
nextapp = NULL;
}
menu_struct::~menu_struct()
{
if (nextmenu == NULL) {
if (prevmenu != NULL)
prevmenu->nextmenu = NULL;
else
glob_menu = NULL;
}
else if (prevmenu == NULL) {
glob_menu = nextmenu;
nextmenu->prevmenu = NULL;
}
else {
if (prevmenu)
prevmenu->nextmenu = nextmenu;
if (nextmenu)
nextmenu->prevmenu = prevmenu;
}
}
app_struct::app_struct()
{
memset((void*)appexe, 0, sizeof(appexe));
memset((void*)workingdir, 0, sizeof(workingdir));
memset((void*)params, 0, sizeof(params));
memset((void*)appname, 0, sizeof(appname));
show = 0;
separator = FALSE;
nextapp = NULL;
prevapp = NULL;
}
app_struct::~app_struct()
{
if (nextapp == NULL) {
if (prevapp != NULL)
prevapp->nextapp = NULL;
}
else if (prevapp == NULL)
nextapp->prevapp = NULL;
else {
prevapp->nextapp = nextapp;
nextapp->prevapp = prevapp;
}
}